package whf.framework.web.servlet;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jdom.Document;
import org.jdom.output.XMLOutputter;

import whf.framework.datasource.DataSource;
import whf.framework.datasource.impl.CollectionDataSource;
import whf.framework.exception.DAOException;
import whf.framework.exception.ServiceNotFoundException;
import whf.framework.ext.DictManagerImp;
import whf.framework.log.Log;
import whf.framework.log.LogFactory;
import whf.framework.meta.MetaFactory;
import whf.framework.service.QueryService;
import whf.framework.util.Base64;
import whf.framework.util.BeanFactory;
import whf.framework.util.ExpireableMap;
import whf.framework.util.StringUtils;
import whf.framework.util.Utils;
import whf.framework.web.Constants;
import whf.framework.xml.DictXmlBuilder;

/**
 * @author wanghaifeng
 *
 */
@SuppressWarnings(value={"unchecked","serial"})
public class XmlOutputServlet extends HttpServlet {
	private static Log log = LogFactory.getLog(XmlOutputServlet.class);
	
	private static Map<String, Document> cache = new ExpireableMap<String, Document>(1000*60*10L);
	
	private boolean cacheable;
	
	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		this.cacheable = "true".equalsIgnoreCase(config.getInitParameter("cacheable"));
	}

	public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/xml; charset=UTF-8");
		String entityClassName = request.getParameter(Constants.BO_CLASS_NAME);
		String queryString = request.getParameter(Constants.QUERY_STRING);
		String dictCategory = request.getParameter(Constants.DICT_CATEGORY);
		String format = request.getParameter("format");
		
		if(queryString == null) queryString = "";
		
		String queryKey = Base64.encode(entityClassName+";"+queryString+";"+dictCategory);
		log.debug(queryKey);
		log.debug("boClassName:"+ entityClassName);
		log.debug("queryString:" + queryString);
		log.debug("dictCategory:"+dictCategory);
		log.debug("format:"+format);
		Document doc = cache.get(queryKey);
		if(doc == null){
			try{
				if(StringUtils.equalsIgnoreCase(format, "TreeXml")){
					
				} else {
					if(StringUtils.equalsIgnoreCase(dictCategory,"SYS_DATATYPE")){ //系统数据类型
						doc = DictXmlBuilder.buildDataTypeDocument();
					} else if(!StringUtils.isEmpty(entityClassName)){
						Class entityClass = Utils.getClassByClassName(entityClassName);
						DataSource dataSource = null;
						if(entityClass == whf.framework.ext.entity.DictItem.class){
							dataSource = DictManagerImp.getDictManager().findByCategoryCode(dictCategory, queryString);
						} else {
							QueryService service = BeanFactory.getService(MetaFactory.findByModelClass(entityClass));
							dataSource = new CollectionDataSource(service.query(queryString));
						}
						log.debug("Fetch from persistent:" + dataSource.size());
						doc = DictXmlBuilder.buildDocument(dataSource, entityClass);
						if(this.cacheable){
							cache.put(queryKey, doc);
						}
					}
				}
			}catch(ServiceNotFoundException e){
				log.error(this, e);
			}catch(DAOException e){
				log.error(this, e);
			}
		} else {
			log.debug("Fetch from cache ");
		}
		if(doc == null){
			doc = DictXmlBuilder.getEmptyDocument();
		}
		OutputStream out = response.getOutputStream();
		XMLOutputter outputer = new XMLOutputter();
		//outputer.output(doc, new java.io.FileOutputStream("e:\\dict.xml"));
		outputer.output(doc, out);
		out.flush();
	}
}
